package ordering.stat;

import ordering.VariableOrdering;
import general.CPA.CPA;
import general.conflictset.ConflictSet;
import general.constraints.VariableConstraints;

public abstract class StaticOrdering implements VariableOrdering{

	byte[] order;			//maps variable to thier order
	byte[] reverseOrder;	//maps the order into the variable
	public StaticOrdering(byte[] order){
		setArray(order);
	}

	protected StaticOrdering(){

	}
	protected void setArray(byte[] order){
		this.order = order;
		this.reverseOrder = new byte[order.length];
		for (byte i=0; i<order.length; i++){
			reverseOrder[order[i]] = i;
		}
	}

	@Override
	public byte max(CPA p, byte id, ConflictSet conflicts){
		byte maxOrder = -1;
		for (byte i=0; i<order[id]; i++){
			if (conflicts.isConflicting(reverseOrder[i])){
				maxOrder = reverseOrder[i];
			}
		}
		return maxOrder;
	}

	@Override
	public byte[] between(CPA p, byte low, byte high) {
		byte orderLow = (byte)(order[low]+1);
		byte orderHigh = order[high];
		byte[] ans = new byte[orderHigh-orderLow];
		for (int i=0; i< orderHigh-orderLow; i++){
			ans[i] = reverseOrder[orderLow+i];	//the agent ordered i
		}
		return ans;
	}

	@Override
	public byte next(CPA p, byte agent, VariableConstraints c) {
		byte position = order[agent];		//get the placing of the agent
		//		System.out.println("<" + agent + ", " + reverseOrder[position+1] + ">");
		return reverseOrder[position+1];	//returns the agent of the next to come placing
	}

	@Override
	public boolean hasNext(CPA p, byte id) {
		return order[id]+1!=order.length;
	}

	@Override
	public boolean isFirst(byte id) {
		return order[id] == 0;
	}

	@Override
	public void removeBigger(CPA p, ConflictSet conflicts, byte id) {
		byte agentOrder = order[id];
		if (agentOrder!=-1){
			agentOrder++;
			for (byte i = agentOrder; i<order.length; i++){
				conflicts.remove(reverseOrder[i]);
			}
		}
	}


	@Override
	public void removeBigger(CPA cpa, byte id) {
		byte agentOrder = order[id];
		for (byte i = agentOrder; i<order.length; i++){
			cpa.remove(reverseOrder[i]);
		}
	}

	@Override
	public byte previous(CPA p, byte agent) {
		return reverseOrder[order[agent]-1];
	}

	@Override
	public boolean isBefore(CPA originCPA, byte cpaCreator, byte maxConflicted) {
		if (order[cpaCreator]==-1) return false;
		if (order[maxConflicted]==-1) return true;
		if (order[cpaCreator] < order[maxConflicted]) return true;
		else return false;
	}
}
